home *** CD-ROM | disk | FTP | other *** search
- /*
- * WICONSETTER A companion utility to wIconify. wIconSetter allows
- * you to specify custom icons for windows ans screens
- * that normally use the default icons.
- *
- * wIconFileIO.c Handles low-level file activity.
- *
- * Copyright 1990 by Davide P. Cervone, all rights reserved.
- * You may use this code, provided this copyright notice is kept intact.
- */
-
- #include <exec/types.h>
- #include <stdio.h>
- #include "wIconFile.h"
-
- FILE *InFile; /* Main file pointer */
- int EndOfFile; /* TRUE if at end-of-file */
-
- static int LineCount; /* Number of lines read */
- static char Line[MAXLINE+2]; /* Line buffer */
- static short LinePos; /* current position in line */
- static short WrdStart,WrdEnd; /* Where the current word starts and ends */
-
- char NextChar; /* the next character of the file */
- char Word[MAXLINE+1]; /* the word buffer */
-
- static FILE *OldFile; /* Saved file for DEFAULT_ICON command */
- static int OldLineCount; /* Saved line count for old file */
-
-
- #define INVERSE "\033[32;41m"
- #define NORMAL "\033[m"
- #define COLORED "\033[32;40m"
-
-
- /*
- * ShowError()
- *
- * If the word starts and ends at the same character, move ahead so something
- * will be displayed.
- * Get the first character of the word, and end the line there.
- * Set the text color and print the first part of the line.
- * Put back the first character of the word, and save the last one.
- * Print the word in inverted lettering and go back to colored letters.
- * Put back the last letter of the word and print the rest of the line.
- * Go back to normal lettering and print the error message with a line number.
- * If the icon file is open, indicate that.
- */
-
- void ShowError(s,x1,x2,x3)
- char *s,*x1,*x2,*x3;
- {
- char c;
-
- if (WrdStart == WrdEnd) WrdEnd++;
- c = Line[WrdStart]; Line[WrdStart] = 0;
- printf(COLORED);
- printf("%s",Line);
- Line[WrdStart] = c; c = Line[WrdEnd]; Line[WrdEnd] = 0;
- printf(INVERSE);
- if (EndOfFile || Line[WrdStart] < ' ') printf(" ");
- else printf("%s",&Line[WrdStart]);
- printf(COLORED);
- Line[WrdEnd] = c; if (c) printf("%s",&Line[WrdEnd]); else printf("\n");
- printf(NORMAL);
- printf(s,x1,x2,x3);
- printf(" at line %d",LineCount);
- if (OldFile) printf(" of Icon File");
- printf("\n");
- }
-
-
- /*
- * Expected()
- *
- * If we are at the end of file, indicate this.
- * If the word is a single character (or no characters)
- * If the character is printable, use it,
- * Otherwise, convert it to a word it control character notation.
- * Print the message saying what was seen and what was expected.
- */
-
- void Expected(s)
- char *s;
- {
- char *Seen = &Word[0];
- char c = Line[WrdStart];
-
- if (EndOfFile) Seen = "End-of-File"; else
- if (WrdEnd < WrdStart+2)
- {
- if ((c >= ' ' && c < 0x7F) || c > 0xA0) Seen = " ", Seen[0] = c;
- else
- {
- switch(c)
- {
- case '\n':
- Seen = "End-of-Line";
- break;
-
- case ' ':
- Seen = "Space";
- break;
-
- case '\t':
- Seen = "TAB";
- break;
-
- case '\033':
- Seen = "ESC";
- break;
-
- case '\0':
- Seen = "NULL";
- break;
-
- case 0x7F:
- Seen = "DEL";
- break;
-
- default:
- Seen = "^ ";
- Seen[1] = (c & 0x1F) + '@';
- break;
- }
- }
- }
- ShowError("'%s' seen where %s was expected",Seen,s);
- }
-
-
- /*
- * GetNextLine()
- *
- * If we can read a line from the file,
- * Mark the end of line (in case the maximum of the buffer was used)
- * Clear the position markers, and count the line.
- * Get the next character on the line.
- * Otherwise,
- * Clear the line and set the positions to the end of the line.
- * Mark the end of file (any error is treated as EOF).
- */
-
- static void GetNextLine()
- {
- if (fgets(Line,MAXLINE,InFile))
- {
- Line[MAXLINE] = '\n';
- Line[MAXLINE+1] = 0;
- LinePos = WrdStart = WrdEnd = 0;
- LineCount++;
- NextChar = Line[LinePos];
- } else {
- NextChar = '\n'; LinePos = WrdStart = WrdEnd = MAXLINE;
- EndOfFile = TRUE;
- }
- }
-
-
- /*
- * GetNextChar()
- *
- * Get the next character on the line and increment the position.
- * Set the word positions to the current position.
- */
-
- void GetNextChar()
- {
- NextChar = Line[++LinePos];
- WrdStart = WrdEnd = LinePos;
- }
-
-
- /*
- * SkipComments()
- *
- * While we are at the beginning of a comment (indicated by '/*')
- * Move past the comment characters and increment the comment counter
- * Get the next character.
- * While we are still within a coment,
- * and until we reach a comment terminator or end-of-file,
- * If we are at the end of a line, read the next line,
- * If we are at the beginning of a nested comment,
- * Increment the nexted count and move past the comment characters.
- * Otherwise, go on to the next character.
- * If we are at the end of the file, show an error (unbalanced comments).
- * Otherwise, skip the end-comment characters.
- * Decrement the comment nesting count.
- * If the next character is the rest-of-line comment character,
- * or if we are at the end of the file, move to the end of the line.
- */
-
- void SkipComments()
- {
- int Nested = 0;
-
- while (NextChar == '/' && Line[LinePos+1] == '*')
- {
- LinePos += 2; Nested++;
- NextChar = Line[LinePos++];
- while (Nested)
- {
- while ((NextChar != '*' || Line[LinePos] != '/') && !EndOfFile)
- {
- if (NextChar == '\n' || NextChar == '\0') GetNextLine(); else
- if (NextChar == '/' && Line[LinePos] == '*')
- Nested++, NextChar = Line[++LinePos];
- else NextChar = Line[LinePos++];
- }
- if (EndOfFile)
- {
- WrdStart = WrdEnd = MAXLINE;
- Expected("End-of-Comment");
- } else NextChar = Line[++LinePos];
- Nested--;
- }
- }
- if (EndOfFile || NextChar == ';') NextChar = Line[LinePos=MAXLINE];
- }
-
-
- /*
- * SkipSpaces()
- *
- * First skip any comments.
- * While the next character is white-space,
- * Skip characters until it is not white space,
- * Then skip comments and do it again.
- */
-
- void SkipSpaces()
- {
- SkipComments();
- while (NextChar == ' ' || NextChar == '\t')
- {
- do NextChar = Line[++LinePos];
- while (NextChar == ' ' || NextChar == '\t');
- SkipComments();
- }
- }
-
-
- /*
- * ReadNextLine()
- *
- * While there is more in the file, and the current line is blank
- * Get the next line of the file and skip any comments.
- * Do this until there is actually some real data to look at.
- * Set the word positions to the current location.
- */
-
- void ReadNextLine()
- {
- while (!EndOfFile && (NextChar == 0 || NextChar == '\n'))
- {
- GetNextLine();
- SkipSpaces();
- }
- WrdStart = WrdEnd = LinePos;
- }
-
-
- /*
- * SkipChar()
- *
- * If we are at the end of the line, read the next one,
- * Otherwise, move to the next non-blank character.
- */
-
- void SkipChar()
- {
- if (NextChar == '\n') ReadNextLine();
- else NextChar = Line[++LinePos], SkipSpaces();
- }
-
-
- /*
- * SkipLine()
- *
- * No matter where we are on the current line, go on to the next line
- * and skip spaces. Mark the current word positions.
- */
-
- void SkipLine()
- {
- GetNextLine(); SkipSpaces();
- WrdStart = WrdEnd = LinePos;
- }
-
-
- /*
- * ReadNextChar()
- *
- * Get the next character and mark the beginning of a word.
- * Skip any spaces after the current character.
- */
-
- void ReadNextChar()
- {
- NextChar = Line[++LinePos];
- WrdStart = WrdEnd = LinePos;
- SkipSpaces();
- }
-
-
- /*
- * ReadAWord()
- *
- * Begin the word at the current location.
- * While the next character is a letter (or a number if they are allowed)
- * Add it to the word buffer and go to the next character
- * If the word has at least one character, mark the end of the word,
- * Otherwise, the word is a single special character.
- * Mark the end of the word in the line buffer and skip trailing spaces.
- */
-
- void ReadAWord(Numbers)
- int Numbers;
- {
- short i=0;
-
- WrdStart = LinePos;
- while ((NextChar >= 'A' && NextChar <= 'Z') ||
- (NextChar >= 'a' && NextChar <= 'z') ||
- (NextChar >= '0' && NextChar <= '9' && Numbers) ||
- NextChar == '_')
- {
- Word[i++] = NextChar;
- NextChar = Line[++LinePos];
- }
- if (i)
- {
- Word[i] = 0;
- } else {
- Word[0] = NextChar; Word[1] = 0;
- NextChar = Line[++LinePos];
- }
- WrdEnd = LinePos;
- SkipSpaces();
- }
-
-
- /*
- * ReadNextWord()
- *
- * Read a word without allowing numbers as part of the word.
- */
-
- void ReadNextWord()
- {
- ReadAWord(FALSE);
- }
-
-
- /*
- * ReadExtendedWord()
- *
- * Read a word and allow numbers as part of the word.
- */
-
- void ReadExtendedWord()
- {
- ReadAWord(TRUE);
- }
-
-
- /*
- * ReadNextInteger()
- *
- * Get the first digit of the number.
- * If it is a minus sign, add it to the number and move on.
- * While the next character is a digit, add it to the number and move on.
- * Mark the end of the word, and skip blanks.
- */
-
- void ReadNextInteger()
- {
- short i=0;
-
- NextChar = Line[LinePos=WrdStart];
- if (NextChar == '-')
- {
- Word[i++] = NextChar;
- NextChar = Line[++LinePos];
- }
- while (NextChar >= '0' && NextChar <= '9')
- {
- Word[i++] = NextChar;
- NextChar = Line[++LinePos];
- }
- Word[i] = 0;
- WrdEnd = LinePos;
- SkipSpaces();
- }
-
-
- /*
- * ReadFullLine()
- *
- * Get the first letter of the word.
- * If the first character is a quote, flag it and move past it.
- * While we are not at the end of the line (or at an end quote)
- * Add the character into the word buffer and move on.
- * If we are looking for a close quote
- * and the next character is a quoted quote,
- * add a single quote into the buffer and skip over the quotes.
- * Mark the end of the word (ie, line).
- * If we were looking for quotes, then
- * If we didn't find a closing quote, show an error, otherwise skip
- * over the close-quote.
- * Skip blanks after the string.
- * Otherwise, strip off trailing blanks from the string.
- */
-
- void ReadFullLine()
- {
- short i = 0;
- int Quoted = FALSE;
-
- NextChar = Line[LinePos=WrdStart];
- if (NextChar == '\'')
- {
- Quoted = TRUE;
- NextChar = Line[WrdStart=++LinePos];
- }
- while (NextChar != '\n' && (NextChar != '\'' || Quoted == FALSE))
- {
- Word[i++] = NextChar;
- NextChar = Line[++LinePos];
- if (Quoted)
- {
- if (NextChar == '\'' && Line[LinePos+1] == '\'')
- {
- Word[i++] = NextChar;
- LinePos += 2;
- NextChar = Line[LinePos];
- }
- }
- }
- WrdEnd = LinePos;
- Word[i--] = 0;
- if (Quoted)
- {
- if (NextChar == '\n') ShowError("Quoted string not terminated");
- else NextChar = Line[++LinePos];
- SkipSpaces();
- } else {
- while (i >= 0 && Word[i] == ' ') Word[i--] = 0;
- }
- }
-
-
- /*
- * Reread()
- *
- * Go back to be beginning of the word and start reading again.
- */
-
- void Reread()
- {
- LinePos = WrdStart;
- NextChar = Line[LinePos];
- }
-
-
- /*
- * WordToUpper()
- *
- * Look through the word buffer and convert lower case letters to uppper
- * case ones.
- */
-
- void WordToUpper()
- {
- char *s = &Word[0];
-
- while (*s)
- {
- if (*s >= 'a' && *s <= 'z') *s = *s - 'a' + 'A';
- s++;
- }
- }
-
-
- /*
- * OpenFile()
- *
- * Attempt to open the specified file.
- * If successful,
- * Set the error status and line counters and read the first line
- * Return TRUE if file openned OK.
- */
-
- int OpenFile(Name)
- char *Name;
- {
- int status = FALSE;
-
- InFile = fopen(Name,"r");
- if (InFile)
- {
- EndOfFile = FALSE; LineCount = 0;
- ReadNextLine();
- status = TRUE;
- }
- return(status);
- }
-
-
- /*
- * CloseFile()
- *
- * Close the file and clear the file pointer.
- */
-
- void CloseFile(theFile)
- FILE *theFile;
- {
- fclose(theFile);
- if (theFile == InFile) InFile = NULL;
- }
-
-
- /*
- * SaveOpenFile()
- *
- * Save the old file pointer and old line count.
- * Clear the file pointer for future use.
- */
-
- void SaveOpenFile()
- {
- OldFile = InFile;
- OldLineCount = LineCount;
- InFile = NULL;
- }
-
-
- /*
- * RestoreFile()
- *
- * If there was an old file open,
- * Get back the old pointer and line count,
- * Reset the status, and move to the end of the line.
- * Clear the save pointer for future use.
- */
-
- void RestoreFile()
- {
- if (OldFile)
- {
- InFile = OldFile;
- LineCount = OldLineCount;
- EndOfFile = FALSE;
- NextChar = Line[LinePos=MAXLINE];
- OldFile = NULL;
- }
- }
-